package com.enation.app.javashop.buyer.api.goods;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.enation.app.javashop.core.goods.listener.GoodsQuantityEvent;
import com.enation.app.javashop.core.goods.listener.QuantityTypeEnum;
import com.enation.app.javashop.core.goods.model.dto.ShipCalculateDTO;
import com.enation.app.javashop.core.goodssearch.enums.GoodsSearchType;
import com.enation.app.javashop.core.goodssearch.model.GoodsSearchDTO;
import com.enation.app.javashop.core.goodssearch.model.GoodsSearchLine;
import com.enation.app.javashop.core.goodssearch.model.GoodsWords;
import com.enation.app.javashop.core.goodssearch.service.GoodsSearchManager;
import com.enation.app.javashop.core.goodssearch.service.impl.GoodsShipCalculator;
import com.enation.app.javashop.core.shop.service.ShopManager;
import com.enation.app.javashop.framework.cache.Cache;
import com.enation.app.javashop.framework.database.Page;
import com.enation.app.javashop.framework.util.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author fk
 * @version v2.0
 * @Description: 商品全文检索
 * @date 2018/6/1915:55
 * @since v7.0.0
 */
@RestController
@RequestMapping("/goods/search")
@Api(description = "商品检索相关API")
public class GoodsSearchBuyerController {

    @Autowired
    private GoodsSearchManager goodsSearchManager;
    @Autowired
    private GoodsShipCalculator goodsShipCalculator;
    @Autowired
    private Cache cache;
    @Autowired
    private ShopManager shopManager;
    @Autowired
    private ApplicationContext context;

    private static String CATEGORY_KEY = "category_map";

    @ApiOperation(value = "查询商品列表")
    @GetMapping
    public Page searchGoods(@ApiIgnore Integer pageNo, @ApiIgnore Integer pageSize, GoodsSearchDTO goodsSearch) {

        goodsSearch.setPageNo(pageNo);
        goodsSearch.setPageSize(pageSize);
        Page search = null;
        String searchType = StringUtils.isEmpty(goodsSearch.getSearchType()) ? GoodsSearchType.ALL.name() : goodsSearch.getSearchType();
        goodsSearch.setSearchType(searchType);
        // 商城搜索
        if (searchType.equals(GoodsSearchType.GLOBAL.name()) || searchType.equals(GoodsSearchType.ALL.name())) {
            search = goodsSearchManager.search(goodsSearch);
            // 取出查询出的商品
            List<GoodsSearchLine> goodsSearchLineList = search.getData();
            List<GoodsSearchLine> goodsSearchLines = new ArrayList<>();
            // 将查询的商品转为map
            Map<Integer, GoodsSearchLine> goodsSearchLineMap = goodsSearchLineList.stream().collect(Collectors.toMap(GoodsSearchLine::getGoodsId, Function.identity(), (oldVal, currVal) -> currVal));
            String goodsIds = goodsSearch.getGoodsIds();
            if(!StringUtil.isEmpty(goodsIds)){
                String[] goodsIdsStr = goodsIds.split(",");
                // 排序
                for (String goodId : goodsIdsStr) {
                    GoodsSearchLine goodsSearchLine = goodsSearchLineMap.get(Integer.parseInt(goodId));
                    goodsSearchLines.add(goodsSearchLine);
                }
                search.setData(goodsSearchLines);
            }
        }
        return search;
    }

    @ApiOperation(value = "查询商品选择器")
    @GetMapping("/selector")
    public Map searchGoodsSelector(GoodsSearchDTO goodsSearch) {

        return goodsSearchManager.getSelector(goodsSearch);
    }

    @ApiOperation(value = "查询商品分词对应数量")
    @ApiImplicitParam(name = "keyword", value = "搜索关键字", required = true, dataType = "string", paramType = "query")
    @GetMapping("/words")
    public List<GoodsWords> searchGoodsWords(String keyword) {

        return goodsSearchManager.getGoodsWords(keyword);
    }


    /**
     * 根据用户当前位置坐标 计算快递费 配送费
     * JFENG
     * @param goodsId
     * @param userLat
     * @param userLng
     * @return
     */
    @ApiOperation(value = "查看商品配送信息", notes = "查看商品配送信息")
    @GetMapping(value = "/ship/{goods_id}/{user_lat}/{user_lng}")
    public ShipCalculateDTO getShipInfo(@PathVariable("goods_id") Integer goodsId
            , @PathVariable("user_lat") Double userLat
            , @PathVariable("user_lng") Double userLng) {
        // 本地商品需要用户经纬度坐标信息
        GoodsSearchDTO goodsSearchDTO = new GoodsSearchDTO();
        goodsSearchDTO.setGoodsId(goodsId);
        goodsSearchDTO.setUserLat(userLat);
        goodsSearchDTO.setUserLng(userLng);

        // 查询ES商品
        GoodsSearchLine goodsByLocation = goodsSearchManager.getGoodsByLocation(goodsSearchDTO);

        // 计算配送信息
        ShipCalculateDTO shipCalculateDTO = new ShipCalculateDTO();

        // 同城配送
        if (goodsByLocation.getIsLocal() == 1) {
            shipCalculateDTO = goodsShipCalculator.calculateLocal(goodsByLocation);
        }

        // 快递配送
        if (goodsByLocation.getIsGlobal() == 1) {
            if (shipCalculateDTO.getDistance() == null) {
                BigDecimal distance = BigDecimal.valueOf(Double.valueOf(goodsByLocation.getSortFiled()[0].toString()));
                shipCalculateDTO.setDistance(distance);
            }
            shipCalculateDTO.setAllowGlobalShip(1);
            goodsShipCalculator.calculateGlobal(shipCalculateDTO);
        }

        shipCalculateDTO.setIsLocal(goodsByLocation.getIsLocal());
            shipCalculateDTO.setIsGlobal(goodsByLocation.getIsGlobal());
        shipCalculateDTO.setIsSelfTake(goodsByLocation.getIsSelfTake());

        // 店铺营业时间(只有商品支持同城配送的情况下才可以判断营业时间)
        if (shipCalculateDTO.getIsLocal() == 1 && shipCalculateDTO.getIsGlobal() == 0) {
            shipCalculateDTO.setShopIsOPen(shopManager.checkIsWorkTime(goodsByLocation.getSellerId()));
        } else {
            shipCalculateDTO.setShopIsOPen(true);
        }

        return shipCalculateDTO;
    }

    /**
     * APP端搜索类目查询
     * JFNEG
     * @return
     */
    @ApiOperation(value = "APP端搜索排序方式列表")
    @GetMapping("/category")
    public List<Map<String, Object>> getCategory() {
        String categoryStr = (String) cache.get(CATEGORY_KEY);
        List<Map<String, Object>> categoryMap = JSON.parseObject(categoryStr, new TypeReference<List<Map<String, Object>>>() {
        });
        return categoryMap;
    }

    /**
     * APP端搜索搜索排序方式管理
     * JFNEG
     * @param categoryMap
     * @return
     */
    @ApiOperation(value = "APP端搜索排序方式更新")
    @PostMapping("/updateCategory")
    public boolean updateCategory(@RequestBody List<Map<String, Object>> categoryMap) {
        cache.remove(CATEGORY_KEY);
        cache.put(CATEGORY_KEY, JSON.toJSONString(categoryMap));
        return true;
    }


    @ApiOperation(value = "测试发布订阅")
    @PostMapping("/test")
    public boolean testQuantity(@RequestParam String  param) {
        GoodsQuantityEvent goodsQuantityEvent = new GoodsQuantityEvent(this, param, QuantityTypeEnum.SECKILL_GOODS);
        context.publishEvent(goodsQuantityEvent);
        return true;
    }

}
